/**
 * Created by leo on 10/25.
 */
(function () {
    'use strict';
    angular.module('Menu', ['Shortcut'])
        .factory('menuService', function ($http, urlPrefix, parseHost) {
            var currentMenus = [], loadingMenus = false;
            return {
                hoveredMenu: null,
                selectedMenu: null,
                getCurrentMenus: function () {
                    return currentMenus;
                },
                setCurrentMenus: function (menus) {
                    currentMenus.length = 0;
                    angular.forEach(menus, function (menu) {
                        this.push(menu);
                    }, currentMenus);
                },
                loadSubSystems: function () {
                    return $http.get(urlPrefix + '/subSystems.do')
                        .then(function (resp) {
                            return resp.data;
                        });
                },
                loadMenus: function (systemId) {
                    loadingMenus = true;
                    return $http.get(urlPrefix + '/menus.do?systemId=' + systemId, {cache: true})
                        .then(function (resp) {
                            var childrenMap = {}, rootModule;
                            angular.forEach(resp.data, function (module) {
                                if (module.MODULE_ID == systemId) return;
                                var menu = {
                                    id: module.MODULE_ID,
                                    pId: module.PARENT_ID,
                                    name: module.MODULE_NAME,
                                    url: parseHost(module.MODULE_PATH),
                                    target: module.MODULE_TARGET,
                                    pathText: module.MODULE_DIRECTORY,
                                    isRefresh: module.IS_REFRESH
                                };
                                if (angular.isArray(childrenMap[menu.pId])) {
                                    childrenMap[menu.pId].push(menu);
                                } else {
                                    childrenMap[menu.pId] = [menu];
                                }
                            });
                            (function buildTree(rootModule) {
                                var children = childrenMap[rootModule.id];
                                if (!angular.isArray(children)) return;
                                rootModule.subMenus = children;
                                angular.forEach(children, function (module) {
                                    buildTree(module);
                                });
                            })(rootModule = {id: systemId});
                            loadingMenus = false;
                            return rootModule.subMenus;
                        });
                },
                isLoadingMenus: function () {
                    return loadingMenus;
                }
            };
        })
        .directive('menuBar', function (menuService, tabService, ShortcutService, $window, $timeout,urlMap) {
            return {
                restrict: 'A',
                scope: {},
                link: function (scope, iElement) {
                    scope.menuService = menuService;
                    scope.clickMenu = function (menu) {
                        if (menu.url) {
                            var url = menu.url;
                            if (menu.isRefresh == "1") {
                                url += (url.indexOf('?') != -1 ? "&" : "?") + Math.random().toString(36);
                            }
                            switch (menu.target) {
                                case "self":
                                    $window.location.href = url;
                                    return;
                                case "blank":
                                    $window.open(url, menu.name);
                                    break;
                                case "tab":
                                default:
                                    tabService.addTab({
                                        id: menu.id,
                                        name: menu.name,
                                        url: url,
                                        pathText: menu.pathText
                                    });
                            }
                            menuService.hoveredMenu = null;
                        }
                    };
                    scope.closeMenuPop = function () {
                        menuService.hoveredMenu = null;
                    };
                    scope.mouseOverMenu = function ($event, $index) {
                        var menu = angular.element($event.target);
                        var isMouseOver = true;
                        var leaveCallback = function () {
                            isMouseOver = false;
                        };
                        menu.mouseleave(leaveCallback);
                        $timeout(function () {
                            if (isMouseOver) {
                                var menuOffset = menu.offset();
                                scope.menuCenterOffsetX = menu.outerWidth() / 2 + menuOffset.left;
                                scope.menuPopTop = menuOffset.top + menu.outerHeight();
                                menuService.hoveredMenu = $index;
                            }
                            menu.unbind("mouseleave", leaveCallback);
                        }, 100);
                    };
                    scope.getSubMenus = function () {
                        if (menuService.hoveredMenu >= 0) {
                            var currentMenu = menuService.getCurrentMenus()[menuService.hoveredMenu];
                            return (currentMenu && currentMenu.subMenus) || [];
                        }
                    };

                    var shortcuts = [];
                    ShortcutService.getShortcuts().then(function (data) {
                        shortcuts = data;
                        angular.forEach(shortcuts, function (shortcut) {
                            if (shortcut && shortcut.shortcutPath) shortcuts['path:' + shortcut.shortcutPath] = true;
                        });
                    });
                    ShortcutService.addChangeListener(function () {
                        shortcuts = this;
                        angular.forEach(shortcuts, function (shortcut) {
                            if (shortcut && shortcut.shortcutPath) shortcuts['path:' + shortcut.shortcutPath] = true;
                        });
                    });
                    scope.isInShortcuts = function (url) {
                        url = urlMap[url.replace(/[&?]0\.[a-z0-9]+$/, '')];
                        return shortcuts['path:' + url] == true;
                    };
                    scope.clickShortcutStatus = function (menu, $event) {
                        $event.stopPropagation();
                        $event.cancelBubble = true;
                        var url = urlMap[menu.url.replace(/[&?]0\.[a-z0-9]+$/, '')];
                        if (scope.isInShortcuts(url)) {
                            ShortcutService.removeShortcut(url);
                        } else {
                            ShortcutService.addShortcut({
                                shortcutPath: url,
                                shortcutName: menu.name,
                                menuId: menu.id
                            });
                        }
                    };
                },
                replace: true,
                templateUrl: 'app/menu/menu-bar.html'
            };
        })
        .directive('subsystemList', function (menuService, tabService, $window, Promise, $timeout, parseHost) {
            return {
                restrict: 'A',
                scope: {},
                link: function (scope, elem) {
                    Promise.when(menuService.loadSubSystems()).then(function (subSystems) {
                        var iterLen, sysLen = 0, sysMaxLen = Math.max(($window.document.documentElement.clientWidth - 750) / 8, 50) - 3;
                        scope.subSystems = [];
                        scope.hiddenSubSystems = [];
                        scope._showMoreBtm = false;
                        for (var i = 0; i < subSystems.length; i++) {
                            var vo = subSystems[i].MODULE_NAME,
                                lo = vo.length,// 字符串长度
                                len = lo + 2;//实际字符串长度
                            for (var j = 0, charCode = vo.charCodeAt(j); j < lo; j++) {
                                if (charCode < 27 || charCode > 126) { // 双字节字符 或 [^\x00-\xff]
                                    len++;
                                }
                            }
                            sysLen += len;
                            if (sysLen > sysMaxLen) {
                                scope.hiddenSubSystems.push(subSystems[i]);
                                continue;
                            }
                            iterLen = i+1;
                            scope.subSystems.push(subSystems[i]);
                        }
                        if (sysLen > sysMaxLen) {
                            scope._showMoreBtm = true;
                        }
                        for (var i = 0; i < iterLen; i++) {
                            var subSystem = scope.subSystems[i];
                            scope.subSystems['sys$' + subSystem['MODULE_ID']] = subSystem;
                        }
                        for (var i = 0; i >= iterLen && i < scope.subSystems.length; i++) {
                            var subSystem = scope.subSystems[i];
                            scope.hiddenSubSystems['sys$' + subSystem['MODULE_ID']] = subSystem;
                        }
                        /**
                         * 通过systemId获取子系统对象
                         * @param systemId
                         * @returns {*}
                         */
                        scope.subSystem = function (systemId) {
                            return scope.subSystems['sys$' + systemId];
                        };
                        /**
                         * 调整子系统列表的选择状态，如果不设置参数表示获取当前状态
                         * @param show
                         * @param $event
                         * @returns {*}
                         */
                        scope.showHiddenSysList = function (show, $event) {
                            if (show == true) {
                                var $sysList = angular.element($event.target);
                                var isMouseOver = true;
                                var leaveCallback = function () {
                                    isMouseOver = false;
                                };
                                $sysList.mouseleave(leaveCallback);
                                $timeout(function () {
                                    $sysList.unbind("mouseleave", leaveCallback);
                                    if (isMouseOver) {
                                        scope._showHiddenSysList = true;
                                    }
                                    $sysList.unbind("mouseleave", leaveCallback);
                                }, 100);
                            } else {
                                if ($event !== undefined && $event.relatedTarget.parentNode.id != 'subsystem-hidden-bar') {
                                    scope._showHiddenSysList = false;
                                }
                            }
                        };
                        scope.changeSystem = function (systemId) {
                            var subSystem = scope.subSystem(systemId);
                            if (subSystem && subSystem.MODULE_PATH) {
                                var modulepath = parseHost(subSystem.MODULE_PATH);
                                switch (subSystem.MODULE_TARGET) {
                                    case "tab":
                                        tabService.addTab({
                                            id: subSystem.MODULE_ID,
                                            name: subSystem.MODULE_NAME,
                                            url: modulepath
                                        });
                                        break;
                                    case "self":
                                        $window.location.href = modulepath;
                                        return;
                                    case "blank":
                                    default:
                                        $window.open(modulepath);
                                }
                            }
                            scope.selectedSystem = systemId;
                            menuService.setCurrentMenus([]);
                            Promise.when(menuService.loadMenus(systemId)).then(function (menus) {
                                menuService.setCurrentMenus(menus);
                            });
                            scope.showHiddenSysList(false);
                            return subSystem;
                        };
                        scope.changeSystem(scope.subSystems[0]['MODULE_ID']);
                    })
                },
                templateUrl: 'app/menu/subsystem-list.html'
            };
        })
    ;
}());